use crate::dbs::sqlite::Peer;
use async_graphql::{Context, ID};
use derivative::Derivative;
use rbatis::rbatis::Rbatis;
use serde::{Deserialize, Serialize};
use serde_json::Result;

use crate::features::gfilter::{
  self, DateTimeFilterIn, IntFilterIn, StringExactFilterIn, StringPatternFilterIn,
};
use crate::features::gnode::KV;
use crate::features::spreadsheet::modelsdbo::{EdgeDBO, NodeDBO};


#[derive(async_graphql::SimpleObject, Serialize, Deserialize, Clone)]
#[graphql(complex)]
#[derive(Derivative)]
#[derivative(Default)]
/// this is Nodetity ,i.e. NodeEntity
pub struct CellNodetity {
  /// the node id
  pub id: ID,
  pub body: String,
  pub created_at: Option<i64>,
  pub updated_at: Option<i64>,
}

#[derive(async_graphql::SimpleObject, Serialize, Deserialize, Clone, Derivative)]
#[derivative(Default)]
/// this is Nodedge, i.e. NodeEdge
pub struct CellNodedge {
  /// subject id , should reference to Nodeity.id
  pub subject: ID,
  /// the relationship of subject to object, e.g. (user_abc) is (tester) of (quiz_xyz)
  pub predicate: String,
  /// object id, should reference to Nodeity.id  
  pub object: ID,
  /// the edge properties
  pub properties: String,
  pub created_at: Option<i64>,
  pub updated_at: Option<i64>,
}

#[async_graphql::ComplexObject]
impl CellNodetity {
  pub async fn from(&self, ctx: &Context<'_>) -> String {
    let mut from = String::new();
    from.push_str(&self.id);
    from.push_str("<");
    from.push_str("nodedbo");
    from.push_str(">");

    from
  }
}

impl From<CellNodeDBO> for CellNodetity {
  fn from(item: NodeDBO) -> Self {
    Nodetity {
      id: ID::from(item.id),
      body: item.body,
      created_at: item.created_at,
      updated_at: item.updated_at,
    }
  }
}

impl From<CellEdgeDBO> for CellNodedge {
  fn from(item: CellEdgeDBO) -> Self {
    CellNodedge {
      subject: ID::from(item.subject),
      predicate: item.predicate,
      object: ID::from(item.object),
      properties: item.properties,
      created_at: item.created_at,
      updated_at: item.updated_at,
    }
  }
}



#[derive(async_graphql::SimpleObject, Serialize, Deserialize, Clone)]
#[graphql(complex)]
#[derive(Derivative)]
#[derivative(Default)]
/// this is Column ,i.e. Column
pub struct Column {
  pub id:u32,
  pub label: String,
  pub type:String,
  pub formula: Option<String>,
}


#[async_graphql::ComplexObject]
impl Column {
  pub async fn from(&self, ctx: &Context<'_>) -> String {
    let mut from = String::new();
    from.push_str(&self.label);
    from.push_str("<");
    from.push_str(&self.label);
    from.push_str(">");

    from
  }
}


#[derive(async_graphql::SimpleObject, Serialize, Deserialize, Clone)]
#[graphql(complex)]
#[derive(Derivative)]
#[derivative(Default)]
/// this is Header ,i.e. Header
pub struct Header {
  pub A: Column,        pub AA: Option<Column>,pub BA: Option<Column>,pub CA: Option<Column>,pub DA: Option<Column>,pub EA: Option<Column>,pub BA: Option<Column>,   
  pub B: Option<Column>,pub AB: Option<Column>,pub BB: Option<Column>,pub CB: Option<Column>,pub DB: Option<Column>,pub EB: Option<Column>,pub BB: Option<Column>,
  pub C: Option<Column>,pub AC: Option<Column>,pub BC: Option<Column>,pub CC: Option<Column>,pub DC: Option<Column>,pub EC: Option<Column>,pub BC: Option<Column>,
  pub D: Option<Column>,pub AD: Option<Column>,pub BD: Option<Column>,pub CD: Option<Column>,pub DD: Option<Column>,pub ED: Option<Column>,pub BD: Option<Column>,
  pub E: Option<Column>,pub AE: Option<Column>,pub BE: Option<Column>,pub CE: Option<Column>,pub DE: Option<Column>,pub EE: Option<Column>,pub BE: Option<Column>,
  pub F: Option<Column>,pub AF: Option<Column>,pub BF: Option<Column>,pub CF: Option<Column>,pub DF: Option<Column>,pub EF: Option<Column>,pub BF: Option<Column>,
  pub G: Option<Column>,pub AG: Option<Column>,pub BG: Option<Column>,pub CG: Option<Column>,pub DG: Option<Column>,pub EG: Option<Column>,pub BG: Option<Column>,
  pub H: Option<Column>,pub AH: Option<Column>,pub BH: Option<Column>,pub CH: Option<Column>,pub DH: Option<Column>,pub EH: Option<Column>,pub BH: Option<Column>,
  pub I: Option<Column>,pub AI: Option<Column>,pub BI: Option<Column>,pub CI: Option<Column>,pub DI: Option<Column>,pub EI: Option<Column>,pub BI: Option<Column>,
  pub J: Option<Column>,pub AJ: Option<Column>,pub BJ: Option<Column>,pub CJ: Option<Column>,pub DJ: Option<Column>,pub EJ: Option<Column>,pub BJ: Option<Column>,
  pub K: Option<Column>,pub AK: Option<Column>,pub BK: Option<Column>,pub CK: Option<Column>,pub DK: Option<Column>,pub EK: Option<Column>,pub BK: Option<Column>,
  pub L: Option<Column>,pub AL: Option<Column>,pub BL: Option<Column>,pub CL: Option<Column>,pub DL: Option<Column>,pub EL: Option<Column>,pub BL: Option<Column>,
  pub M: Option<Column>,pub AM: Option<Column>,pub BM: Option<Column>,pub CM: Option<Column>,pub DM: Option<Column>,pub EM: Option<Column>,pub BM: Option<Column>,
  pub N: Option<Column>,pub AN: Option<Column>,pub BN: Option<Column>,pub CN: Option<Column>,pub DN: Option<Column>,pub EN: Option<Column>,pub BN: Option<Column>,
  pub O: Option<Column>,pub AO: Option<Column>,pub BO: Option<Column>,pub CO: Option<Column>,pub DO: Option<Column>,pub EO: Option<Column>,pub BO: Option<Column>,
  pub P: Option<Column>,pub AP: Option<Column>,pub BP: Option<Column>,pub CP: Option<Column>,pub DP: Option<Column>,pub EP: Option<Column>,pub BP: Option<Column>,
  pub Q: Option<Column>,pub AQ: Option<Column>,pub BQ: Option<Column>,pub CQ: Option<Column>,pub DQ: Option<Column>,pub EQ: Option<Column>,pub BQ: Option<Column>,
  pub R: Option<Column>,pub AR: Option<Column>,pub BR: Option<Column>,pub CR: Option<Column>,pub DR: Option<Column>,pub ER: Option<Column>,pub BR: Option<Column>,
  pub S: Option<Column>,pub AS: Option<Column>,pub BS: Option<Column>,pub CS: Option<Column>,pub DS: Option<Column>,pub ES: Option<Column>,pub BS: Option<Column>,
  pub T: Option<Column>,pub AT: Option<Column>,pub BT: Option<Column>,pub CT: Option<Column>,pub DT: Option<Column>,pub ET: Option<Column>,pub BT: Option<Column>,
  pub U: Option<Column>,pub AU: Option<Column>,pub BU: Option<Column>,pub CU: Option<Column>,pub DU: Option<Column>,pub EU: Option<Column>,pub BU: Option<Column>,
  pub V: Option<Column>,pub AV: Option<Column>,pub BV: Option<Column>,pub CV: Option<Column>,pub DV: Option<Column>,pub EV: Option<Column>,pub BV: Option<Column>,
  pub W: Option<Column>,pub AW: Option<Column>,pub BW: Option<Column>,pub CW: Option<Column>,pub DW: Option<Column>,pub EW: Option<Column>,pub BW: Option<Column>,
  pub X: Option<Column>,pub AX: Option<Column>,pub BX: Option<Column>,pub CX: Option<Column>,pub DX: Option<Column>,pub EX: Option<Column>,pub BX: Option<Column>,
  pub Y: Option<Column>,pub AY: Option<Column>,pub BY: Option<Column>,pub CY: Option<Column>,pub DY: Option<Column>,pub EY: Option<Column>,pub BY: Option<Column>,
  pub Z: Option<Column>,pub AZ: Option<Column>,pub BZ: Option<Column>,pub CZ: Option<Column>,pub DZ: Option<Column>,pub EZ: Option<Column>,pub BZ: Option<Column>,
}


#[async_graphql::ComplexObject]
impl Header {
  pub async fn from(&self, ctx: &Context<'_>) -> String {
    let mut from = String::new();
    from.push_str(&self.A.label);
    from.push_str("<");
    from.push_str(&self.A.label);
    from.push_str(">");

    from
  }
}

